﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Collab.Services.Remote.Entities;
using System.Xml.Serialization;
using System.Xml;
using System.IO;

namespace Collab.Modules.Editing
{
    public static class UnitTestBuilder
    {
        public static IList<Tuple<BufferUpdate, BufferUpdate, IEnumerable<BufferUpdate>>> Updates = new List<Tuple<BufferUpdate, BufferUpdate, IEnumerable<BufferUpdate>>>();
        private static List<UpdateInformation> UpdateInformations = new List<UpdateInformation>();

        public static string PrintSequence()
        {
            StringBuilder sb = new StringBuilder();
            foreach (var item in Updates)
            {
                sb.Append("new BufferUpdate(\"doc1\", new Guid(\"" + item.Item1.Sender.ToString() + "\")," + item.Item1.Revision + ",  new List<Change>()" +
            "{" + 
                "new Change(" + item.Item1.Changes.First().OldStart + "," + item.Item1.Changes.First().OldEnd + "," + item.Item1.Changes.First().Delta + ",\"" + item.Item1.Changes.First().Text + "\")" + 
            "}),");
                sb.AppendLine();
            }

            return sb.ToString();

        }

        public static string PrintCalculations()
        {
            StringBuilder sb = new StringBuilder();
            foreach (var item in Updates)
            {
                if (item.Item1.Revision == item.Item2.Revision)
                {
                    sb.AppendLine("No recalculations of rev:");
                    sb.AppendLine(item.Item1.Revision + " from: " + item.Item1.Sender + " at index:" + item.Item1.Changes.First().OldStart + " text:" + item.Item1.Changes.First().Text);
                }
                else
                {
                    sb.AppendLine("Recalculation of rev:");
                    sb.AppendLine("OLD:" + item.Item1.Revision + " from: " + item.Item1.Sender + " at index:" + item.Item1.Changes.First().OldStart + " text:" + item.Item1.Changes.First().Text);
                    sb.AppendLine("NEW:" + item.Item2.Revision + " from: " + item.Item2.Sender + " at index:" + item.Item2.Changes.First().OldStart + " text:" + item.Item2.Changes.First().Text);

                    sb.AppendLine("CONSIDERED UPDATES");
                    foreach (var consideredUpdate in item.Item3)
                    {
                        sb.AppendLine("\t" + consideredUpdate.Revision + " from: " + consideredUpdate.Sender + " at index:" + consideredUpdate.Changes.First().OldStart + " text:" + consideredUpdate.Changes.First().Text);
                    }
                }

            }

            return sb.ToString();

        }

        public static void PrintDebug(System.IO.Stream stream)
        {
            try
            {
                XmlSerializer xs = new XmlSerializer(typeof(List<UpdateInformation>), new XmlRootAttribute("updates"));
                TextWriter writer = new StreamWriter(stream);
                xs.Serialize(writer, UpdateInformations);
                writer.Close();

            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                stream.Close();
            }
            
            
        }

        public static void AddUpdateInformation(DateTime startTime, BufferUpdate original, DateTime endTime, BufferUpdate newUpdate, BufferUpdate[] consideredUpdates)
        {
            UpdateInformations.Add(new UpdateInformation
            {
                StartTime = startTime,
                EndTime = endTime,
                BeforeUpdate = original,
                AfterUpdate = newUpdate,
                ConsideredUpdates = consideredUpdates,
            });
        }

        

    }

    public class UpdateInformation
    {
        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }
        public BufferUpdate BeforeUpdate { get; set; }
        public BufferUpdate AfterUpdate { get; set; }
        public BufferUpdate[] ConsideredUpdates { get; set; }

    }

}
